package com.example.usbhidtool

import android.Manifest
import android.app.AlertDialog
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbManager
import android.hardware.usb.UsbRequest
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.util.Log
import android.widget.TextView
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import com.easysocket.EasySocket
import com.easysocket.entity.OriginReadData
import com.easysocket.entity.SocketAddress
import com.easysocket.interfaces.conn.SocketActionListener
import com.example.usbhidtool.hid.HidContants
import com.example.usbhidtool.hid.HidDeviceManager
import com.example.usbhidtool.hid.HidMsgManager
import com.example.usbhidtool.hid.bean.*
import com.example.usbhidtool.hid.umessage.UMessage
import com.example.usbhidtool.hid.umessage.UMessageCallBack
import com.example.usbhidtool.tcp.HidMessageHandle
import com.example.usbhidtool.tcp.HidMessageHandle.SocketMsgCallBack
import com.example.usbhidtool.tcp.SocketManager
import com.example.usbhidtool.utils.HidUtil
import com.example.usbhidtool.utils.JsonUtils
import com.example.usbhidtool.utils.MD5Util
import com.example.usbhidtool.utils.TimeUtil
import com.kunminx.architecture.ui.page.DataBindingConfig
import com.zhaoliangji.architecture.ui.page.BaseActivity
import kotlinx.coroutines.*
import java.nio.ByteBuffer
import java.util.*
import kotlin.concurrent.thread
import kotlin.experimental.and

/**
 * HID 设备管理页面
 */
class HidPageActivity : BaseActivity() {

    lateinit var mState: HidPageViewModel

    lateinit var mTvLog: TextView


    //接收USB设备插入后所发送消息的广播接收器
    private var broadcastReceiver: BroadcastReceiver? = null

    //HID设备管理类
    private lateinit var mHidDeviceManager: HidDeviceManager

    //HID消息管理器
    private lateinit var mHidMsgManager: HidMsgManager

    //读写线程锁块
    private val strUsbReadRunning = "LOCKREAD"
    private val strUsbWriteRunning = "LOCKWRITE"

    //为真时退出监视Usb读写的线程
    private var bUsbReadExit = false

    //写未完成
    private var bUsbWriteOK = true

    companion object {
        const val ACTION_GRANT_USB = "LIANGJILAIYE_GRANT_USB"

        //最大包长度 : 511字节
        const val MAXPacketSize = 512

        //1、验机精灵 IP地址和端口号
//        const val socket_address = "171.90.251.238"
        const val socket_address = "yunxiangyou.com"
        const val socket_port = 12971
    }


    override fun initViewModel() {
        mState = getActivityScopeViewModel(HidPageViewModel::class.java)
    }

    override fun getDataBindingConfig(): DataBindingConfig {
        return DataBindingConfig(R.layout.activity_hid_page, BR.vm, mState)
            .addBindingParam(BR.clickListener, ClickProxy())
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mTvLog = findViewById(R.id.tv_log)
        init()
        checkDevices()
        applyPermission()
//        showCloseDialog()
//        testSocket()
    }


    private fun applyPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            // 先判断有没有权限
            if (Environment.isExternalStorageManager()) {
                updateUILog("Android11 文件权限获取成功")
            } else {
                val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
                intent.data = Uri.parse("package:" + this.getPackageName())
                startActivityForResult(intent, 101)
            }
        } else {
            val permissions = arrayOf<String>(Manifest.permission.READ_EXTERNAL_STORAGE)
            ActivityCompat.requestPermissions(this, permissions, 102)
        }
    }

    private fun testSocket() {
        initSocket()
        GlobalScope.launch {
            delay(5000)
            SocketManager.closeConnection(socket_address, socket_port, false)
        }
    }

    private fun checkDevices() {
        val device = mHidDeviceManager.findDevice()
        if (device != null) {
            openHid()
            if (mHidDeviceManager.getConnection() != null) {
                //发送VINFO命令
                mHidMsgManager.sendCmdMsg("VINFO")
            }
        }
    }

    private fun init() {
        //初始化设备管理器
        mHidDeviceManager = HidDeviceManager(this)
        //设置日志输出器
        mHidDeviceManager.setLogPrinter {
            updateUILog(it)
        }
        //初始化消息管理器
        mHidMsgManager = HidMsgManager(this)
        mHidMsgManager.setLogPrinter { data, isSend ->
            updateUILog(data, isSend)
        }
        initBrodCast()
    }

    /**
     *初始化广播接收器
     * 当设备连接、断开、成功授权、拒绝授权时候都能收到对应广播
     */
    private fun initBrodCast() {
        broadcastReceiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                if (intent.action == HidContants.ACTION_GRANT_USB) {
                    //需要判断用户是按下了: [确定] 或 [取消] 按键
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        //标记授权成功
                        updateUILog("收到广播: 已在授权界面取得USB运行期授权")
                        openHid()
                    } else {
                        //标记授权未成功
                        updateUILog("收到广播: 未能在授权界面取得USB运行期授权")
                        showShortToast("未同意授权USB，流程无法继续！！！")
                    }
                } else if (intent.action == UsbManager.ACTION_USB_DEVICE_ATTACHED) {
                    //USB连接广播
                    //判断是否是目标设备
                    val ud = intent.getParcelableExtra<UsbDevice>(UsbManager.EXTRA_DEVICE)
                    val log = "收到广播: 刚插入USB设备--> VID:${ud?.vendorId},PID:${ud?.productId}"
                    updateUILog(log)
                    val device = mHidDeviceManager.findDevice()
                    if (device != null) {
                        updateUILog("检测到目标设备")
                        //检查授权
                        checkHidPermission()
                    } else {
                        updateUILog("没有检测到目标设备")
                    }
                } else if (intent.action == UsbManager.ACTION_USB_DEVICE_DETACHED) {
                    //先执行关闭(因为设备突然拔掉,通讯很可能异常)
                    val ud = intent.getParcelableExtra<UsbDevice>(UsbManager.EXTRA_DEVICE)
                    updateUILog("收到广播: 刚拔出USB设备-->" + " VID=" + ud?.vendorId + " PID=" + ud?.productId)
                    if (mHidDeviceManager.isMyDevice(ud?.vendorId, ud?.productId)) {
                        updateUILog("目标设备被拔出了！")
                        closeHid()
                    }
                }
            }
        }
        //意图过滤器filter
        val filter = IntentFilter()
        filter.addAction(ACTION_GRANT_USB)
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED)
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
        //注册此广播接收器,此广播接收器将只处理上面的filter定义的广播消息
        registerReceiver(broadcastReceiver, filter)
    }

    //检查权限
    private fun checkHidPermission() {
        if (mHidDeviceManager.checkPermission()) {
            //已授权，直接打开连接
            if (mHidDeviceManager.openConnection()) {
                updateUILog("设备打开成功，设备已就绪！！！")
            } else {
                updateUILog("设备打开失败！！！")
            }
        } else {
            //没有授权，申请授权
            updateUILog("设备没有取得授权")
            mHidDeviceManager.requestPermission()
        }
    }

    //打开设备
    private fun openHid() {
        if (mHidDeviceManager.openConnection()) {
            updateUILog("设备打开成功，设备已就绪！！！")
            startMonitor()
        }
    }

    //开始监听设备读写和设备状态
    private fun startMonitor() {
        bUsbReadExit = false
        startWriteThread()
        startReadThread()
        mHidMsgManager.sendCmdMsg("VINFO")
//        GlobalScope.launch {
//            delay(10)
//            startReadThread()
//        }
    }

    private fun startWriteThread() {
        thread {
            updateUILog("开始监听写线程:${Thread.currentThread()}")
            var lastCheckTime = System.currentTimeMillis()
            try {
                while (!bUsbReadExit) {
                    //写操作
                    val curTime = System.currentTimeMillis()
                    val size = mHidMsgManager.getSize()
                    if (curTime - lastCheckTime > 10000) {
                        //10秒检测一次
                        lastCheckTime = curTime
                        updateUILog("持续监控写队列：size=" + size)
                    }
                    synchronized(strUsbWriteRunning) {
                        //不为空，并且上一次已经发送成功
//                        if (size > 8) {
//                            bulkMessage(mHidMsgManager.getOneMessage()!!, mHidMsgManager.getOneMessage()!!)
//                        } else if (size > 0) {
//                            bulkMessage(mHidMsgManager.getOneMessage()!!)
//                        }
                        if (size > 0) {
                            bulkMessage(mHidMsgManager.getOneMessage()!!)
                        }
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
                updateUILog("写线程异常：${e.message}")
                bUsbReadExit = true
            }
            //运行到这里表示循环退出了
            bUsbReadExit = true
            updateUILog("!!!!!!写线程已结束!!!!!!\n")
        }
    }


    fun startReadThread() {
        thread {
            updateUILog("开始监控读线程")
            val connection = mHidDeviceManager.getConnection()
            val epIn = mHidDeviceManager.getInPoint()
            if (connection == null || epIn == null) {
                updateUILog("连接为空，无法开启读线程")
                return@thread
            }
            val readRequest = UsbRequest()
            readRequest.initialize(connection, epIn)
            var readArray: ByteArray
            val rxBuffer = ByteBuffer.allocate(MAXPacketSize)
            var lastCheckTime = System.currentTimeMillis()
            //数据相关
            var bFile = false  //是否在接收文件
            var totalLength = 0 //总数据的长度
            var dataSB = StringBuilder()      //已接收的数据字符串
            var recLength = 0    //已接收的数据或文件长度
            var lastFilePrintTime = 0L    //文件接收打印间隔
            try {
                while (!bUsbReadExit) {
                    val curTime = System.currentTimeMillis()
                    if (curTime - lastCheckTime > 5000) {
                        lastCheckTime = curTime
                        updateUILog("持续监控读线程")
                    }
                    //
                    //
                    for (i in 0 until MAXPacketSize) rxBuffer.put(i, 0.toByte())
                    if (readRequest.queue(rxBuffer, MAXPacketSize)) {
                        val request = connection.requestWait()
                        if (bUsbReadExit) break
                        if (request == readRequest) {
                            synchronized(strUsbReadRunning) {
                                readArray = Arrays.copyOfRange(rxBuffer.array(), 0, MAXPacketSize)
                                val byte1 = readArray[1]
                                if (byte1 == 0xC1.toByte() || byte1 == 0xC2.toByte() || byte1 == 0xF1.toByte()) {
                                    //一个包的长度
                                    var len = 0
                                    val len1 = readArray[2].toShort() and 0xFF
                                    len += len1
                                    val len2 = (readArray[3].toShort() and 0xFF).toInt().shl(8)
                                    len += len2
                                    //内容字节数组,内容大小是len
                                    val contentArray = ByteArray(len)
                                    Arrays.fill(contentArray, 0.toByte())
                                    when (byte1) {
                                        0xC1.toByte() -> {
                                            System.arraycopy(readArray, 4, contentArray, 0, len)
                                            onReceivedCmd(contentArray)
                                        }
                                        0xC2.toByte() -> {
                                            //接收数据，文件初始化
                                            System.arraycopy(readArray, 9, contentArray, 0, 288)
                                            bFile = readArray[4] == 0x01.toByte()
                                            dataSB = StringBuilder()
                                            totalLength = 0
                                            recLength = 0
                                            var i = 0
                                            while (i < 4) {
                                                val shift = i * 8
//                                                totalLength += readArray[i + 5] and 0xFF shl shift
                                                totalLength += (readArray[i + 5].toShort() and 0xFF).toInt()
                                                    .shl(shift)
                                                i++
                                            }
                                            if (bFile) {
                                                updateUILog(
                                                    "===收到文件头信息：长度：length:$totalLength",
                                                    false
                                                )
                                                //解析出文件名和MD5：
                                                val md5ByteArray = ByteArray(32)
                                                System.arraycopy(
                                                    readArray,
                                                    256,
                                                    md5ByteArray,
                                                    0,
                                                    32
                                                )
                                                updateUILog("md5：" + String(md5ByteArray), false)
                                            } else {
                                                updateUILog(
                                                    "===收到数据头信息：长度：length:$totalLength",
                                                    false
                                                )
                                            }


                                        }
                                        0xF1.toByte() -> {
                                            //累积收到的长度
                                            recLength += len
                                            System.arraycopy(readArray, 4, contentArray, 0, len)
                                            if (!bFile) {
                                                //不是文件
                                                dataSB.append(String(contentArray))
                                            } else {
                                                val timePrint = System.currentTimeMillis()
                                                if (timePrint - lastFilePrintTime > 10000) {
                                                    updateUILog(
                                                        "已经接收的文件长度，10秒打印一次：$recLength",
                                                        false
                                                    )
                                                    lastFilePrintTime = timePrint
                                                }
                                            }
                                            //根据长度判断是否接收完毕
                                            if (recLength == totalLength) {
                                                val str = if (bFile) "文件" else "数据"
                                                updateUILog(
                                                    "=====$str 接收完毕=======：totalLength:$recLength",
                                                    false
                                                )
                                                if (!bFile) {
                                                    onReceivedData(dataSB)
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
                bUsbReadExit = true
            }
            bUsbReadExit = true
            updateUILog("====读线程结束====")
        }
    }

    /**
     * 接收到命令
     */
    fun onReceivedCmd(contentArry: ByteArray) {
        try {
            val str = String(contentArry)
            updateUILog("接收到命令：$str", false)
            if (str.contains("liangjitool close", true)) {
                showCloseDialog()
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    private fun showCloseDialog() {
        GlobalScope.launch {
            delay(1000)
            withContext(Dispatchers.Main) {
                AlertDialog.Builder(this@HidPageActivity).setTitle("盒子挂了")
                    .setMessage("请先截图保存，然后断开盒子,并把259M分区内的log.txt拷贝出来保存,然后汇总给@清川")
                    .setCancelable(false)
                    .show()
            }
        }
    }

    /**
     * 接收到数据
     */
    fun onReceivedData(dataSB: StringBuilder) {
        val dataStr = dataSB.toString()
        updateUILog("接收到完整数据start--", false)
        updateUILog(dataStr, false)
        updateUILog("接收到完整数据end--", false)
        parseData(dataStr)
    }

    /**
     * todo 收到的数据的解析
     */
    fun parseData(dataStr: String) {
        try {
            val recBean = JsonUtils.fromJson(dataStr, RecBean::class.java)
//            updateUILog("解析后的数据实体：$recBean")
            if (recBean.type == "device" && recBean.data != null) {
                val cmd = recBean.data.cmd
                if (cmd.isNullOrEmpty()) {
                    updateUILog("cmd为空")
                    return
                }
                when (cmd) {
                    "authorized" -> {
                        parseAuthData(recBean.data)
                    }
                    "init" -> {
                        parseInitData(recBean.data)
                    }
                    "vinfo" -> {
                        parseVinfoData(recBean.data)
                    }
                    "event" -> {
                        parseEventStatus(recBean.data)
                    }
                    "link" -> {
                        parseLinkData(recBean.data)
                    }

                    "install" -> {
                        parseInstallData(recBean.data)
                    }
                    "info" -> {
                        parseInfoData(recBean.data)
                    }
                    "msg" -> {
                        parseMsgData(recBean.data)
                    }
                    "return" -> {
                        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
                            parseReturn(recBean.data)
                        }
                    }
                    else -> {
                        updateUILog("未解析的CMD类型：$cmd")
                    }
                }
            } else {
                updateUILog("数据格式解析异常：")
            }
        } catch (e: Exception) {
            e.printStackTrace()
            updateUILog(e.message ?: "")
        }
    }

    /**
     * 一些命令执行结果的返回
     */
    private fun parseMsgData(recData: RecData) {
        updateUILog("处理msg信息返回")
        val type = recData.type ?: return
        val bStatus = recData.bstatus
        val iStatus = recData.istatus
        when (type) {
            "START" -> {
                if (bStatus == true) {
                    updateUILog("启动成功了")
                } else {
                    updateUILog("启动失败了")
                    showShortToast("启动失败了")
                }
            }
            "receivefile" -> {
                //收到文件返回消息
                if (bStatus == true) {
                    //文件发送成功
                    updateUILog("type=receivefile")
                } else {
                    showShortToast(recData.msg)
                }
            }
            "updateAPP" -> {
                if (bStatus == true) {
                    updateUILog("盒子App更新成功")
                } else {
                    updateUILog("盒子App更新失败")
                }
            }
            "updateFileMD5" -> {
                updateUILog("文件MD5校验不一致")
            }
            "updatePS" -> {
                updateUILog("字段参数有问题")
            }
            "updateData" -> {
                updateUILog("data字段不存在")
            }
            "updateMain" -> {
                if (bStatus == true) {
                    updateUILog("更新主程序命令执行成功")
                } else {
                    updateUILog("更新主程序命令执行失败")
                }
            }

        }
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private fun parseReturn(data: RecData) {
        when (data.istatus) {
            "2" -> {
                val info = data.info as String
                val bInfo = String(Base64.getMimeDecoder().decode(info))
                updateUILog("收到回传数据：$bInfo")
            }
        }
    }

    private fun parseInfoData(data: RecData) {
        updateUILog("处理客户手机基础信息返回")
    }

    private fun parseInstallData(data: RecData) {
        updateUILog("处理安装信息返回")
    }

    /**
     * 处理插入拔出事件消息
     */
    private fun parseEventStatus(data: RecData) {
        updateUILog("处理插拔信息返回")
        val status = data.istatus
        when (status) {
            "1" -> mState.eventStatus.postValue(CmdEventStatus.INSERT)
            "2" -> {
                mState.eventStatus.postValue(CmdEventStatus.OUR)
                mState.connectStatus.postValue(CmdLinkStatus.UNKNOWN)
            }
            else -> {
                mState.eventStatus.postValue(CmdEventStatus.UNKNOWN)
            }
        }
    }

    //处理Link消息
    private fun parseLinkData(recData: RecData) {
        updateUILog("处理link信息返回")
        val status = recData.istatus
        when (status) {
            "-4" -> {
                mState.connectStatus.postValue(CmdLinkStatus.UNKNOWN)
            }
            "-3" -> {
                mState.connectStatus.postValue(CmdLinkStatus.NOT_TRUST)
            }
            "-2" -> {
                mState.connectStatus.postValue(CmdLinkStatus.UNLOCK)
            }
            "-1" -> {
                mState.connectStatus.postValue(CmdLinkStatus.NOT_AGREE)

            }
            "0" -> {
                mState.connectStatus.postValue(CmdLinkStatus.TRUST)
            }
            "1" -> {
                mState.connectStatus.postValue(CmdLinkStatus.START_READ)
            }
            "2" -> {
                mState.connectStatus.postValue(CmdLinkStatus.END_READ)
            }
        }
    }

    /**
     * 启动成功init
     */
    private fun parseInitData(recData: RecData) {
        //todo 这里appVersion,mainVersion未在文档看见
        updateUILog("处理init信息返回")
        val mainVersion = recData.main?.version
        //更新UI
        runOnUiThread {
            mState.deviceVersion.value = mainVersion
        }
        //发送VINFO指令
        mHidMsgManager.sendCmdMsg("VINFO")
    }

    //处理初始化信息
    private fun parseVinfoData(recData: RecData) {
        updateUILog("处理VINFO信息返回")
        val mainVersion = recData.main?.version
        val appAVersion = recData.appA?.version
        val appIVersion = recData.appI?.version
        //更新UI
        runOnUiThread {
            mState.deviceVersion.value = mainVersion
            mState.appAVersion.value = appAVersion
            mState.appIVersion.value = appIVersion
        }
        //发送START指令
        mHidMsgManager.sendCmdMsg("START")
    }

    //处理授权信息
    private fun parseAuthData(recData: RecData) {
        updateUILog("处理auth信息返回")
        when (recData.istatus) {
            "0" -> {
                initSocket()
            }
            "1" -> {
                updateUILog("SOCKET:准备发送授权请求")
                SocketManager.sendAuthorizeMsg(recData.authorized, "$socket_address:$socket_port")
            }
            "2" -> {

            }
            "3" -> {

            }
        }
    }

    //写数据
    fun bulkMessage(vararg msgList: UMessage) {
        mHidDeviceManager.bulkMessage(*msgList) {
            bUsbWriteOK = it
        }
    }

    //关闭设备
    private fun closeHid() {
        bUsbReadExit = true
        mHidDeviceManager.closeUsbPortA()
        mHidMsgManager.reset()
        mState.reset()
    }

    private fun initSocket() {
        SocketManager.createConnection(this, socket_address, socket_port)
        //socket行为监听
        EasySocket.getInstance().subscribeSocketAction(object : SocketActionListener() {
            //连接成功
            override fun onSocketConnSuccess(socketAddress: SocketAddress) {
                super.onSocketConnSuccess(socketAddress)
                Log.e(
                    "SOCKET",
                    "SOCKET--->端口" + socketAddress.ip + ":" + socketAddress.port + "=连接成功"
                )
                updateUILog(
                    "SOCKET--->端口" + socketAddress.ip + ":" + socketAddress.port + "=连接成功",
                    false
                )
                //SocketManager.sendLoginMsg("24");
            }

            //连接失败
            override fun onSocketConnFail(socketAddress: SocketAddress, isNeedReconnect: Boolean) {
                super.onSocketConnFail(socketAddress, isNeedReconnect)
                Log.e(
                    "SOCKET",
                    "SOCKET--->端口" + socketAddress.ip + ":" + socketAddress.port + "=连接失败"
                )
                updateUILog(
                    "SOCKET--->端口" + socketAddress.ip + ":" + socketAddress.port + "=连接失败",
                    false
                )
            }

            override fun onSocketDisconnect(
                socketAddress: SocketAddress,
                isNeedReconnect: Boolean
            ) {
                //这里断开后不重连
                super.onSocketDisconnect(socketAddress, isNeedReconnect)
                Log.e(
                    "SOCKET",
                    "SOCKET--->端口" + socketAddress.ip + ":" + socketAddress.port + "=socket连接被断开"
                )
                updateUILog(
                    "SOCKET--->端口" + socketAddress.ip + ":" + socketAddress.port + "=socket连接被断开",
                    false
                )
            }

            override fun onSocketResponse(
                socketAddress: SocketAddress,
                originReadData: OriginReadData
            ) {
                super.onSocketResponse(socketAddress, originReadData)
                //处理消息
                HidMessageHandle.handleMessage(
                    socketAddress,
                    originReadData,
                    object : SocketMsgCallBack {
                        override fun onSendData(data: ByteArray) {
                            mHidMsgManager.sendDataMsg(data)
                        }

                        override fun onPrintLog(log: String) {
                            updateUILog(log, false)
                        }

                    })
            }

            override fun onSocketResponse(socketAddress: SocketAddress, readData: ByteArray) {
                super.onSocketResponse(socketAddress, readData)
            }

            override fun onSocketResponse(socketAddress: SocketAddress, readData: String) {
                super.onSocketResponse(socketAddress, readData)
            }
        }, "$socket_address:$socket_port")
    }


    //打印一条日志
    /**
     * @param isSend 是否是发送
     */
    fun updateUILog(log: String, isSend: Boolean = true) {
//        if (log.contains("SOCKET").not()) return
        val dir = if (isSend) "=>" else "<="
        val timeStr = TimeUtil.getHMSFormat(System.currentTimeMillis())
        val str = "[$timeStr]$dir$log\n"
        Log.e(TAG, str)
        runOnUiThread {
            mTvLog.append(str)
        }
    }

    inner class ClickProxy {

        //获取版本
        fun clickGetVersion() {
            val str = "V获取双版本"
            mHidMsgManager.sendCmdMsg(str, callBack = UMessageCallBack {
                if (it == 1) {
                    updateUILog("命令$str 发送成功")
                }
            })
        }

        //发送数据
        fun clickSendData() {
            if (mHidMsgManager.isFileSending()) {
                showShortToast("文件传输中，不能传输大数据")
                return
            }
            val str =
                ("V发送数据fuoisdafpjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjweriasjfodsjfpajfdjisdpfajfifaojsdfsapfsj" +
                        "V发送数据fuoisdafpjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjweriasjfodsjfpajfdjisdpfajfifaojsdfsapfsjfd" +
                        "V发送数据fuoisdafpjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjweriasjfodsjfpajfdjisdpfajfifaojsdfsapfsjfd" +
                        "V发送数据fuoisdafpjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjweriasjfodsjfpajfdjisdpfajfifaojsdfsapfsjfd" +
                        "V发送数据fuoisdafpjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjweriasjfodsjfpajfdjisdpfajfifaojsdfsapfsjfd" +
                        "V发送数据fuoisdafpjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjweriasjfodsjfpajfdjisdpfajfifaojsdfsapfsjfd" +
                        "V发送数据fuoisdafpjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjweriasjfodsjfpajfdjisdpfajfifaojsdfsapfsjfd" +
                        "V发送数据fuoisdafpjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjweriasjfodsjfpajfdjisdpfajfifaojsdfsapfsjfd" +
                        "V发送数据fuoisdafpjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjweriasjfodsjfpajfdjisdpfajfifaojsdfsapfsjfd" +
                        "V发送数据fuoisdafpjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjweriasjfodsjfpajfdjisdpfajfifaojsdfsapfsjfd" +
                        "V发送数据fuoisdafpjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjweriasjfodsjfpajfdjisdpfajfifaojsdfsapfsjfd" +
                        "V发送数据fuoisdafpjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjweriasjfodsjfpajfdjisdpfajfifaojsdfsapfsjfdV发送数据fuoisdafpjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjweriasjfodsjfpajfdjisdpfajfifaojsdfsapfsjfd" +
                        "V发送数据fuoisdafpjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjweriasjfodsjfpajfdjisdpfajfifaojsdfsapfsjfd" +
                        "V发送数据fuoisdafpjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjweriasjfodsjfpajfdjisdpfajfifaojsdfsapfsjfd" +
                        "fd88888888end").toByteArray(charset("UTF-8"))
            mHidMsgManager.sendDataMsg(str)
        }

        //发送APK
        fun clickSendAPK() {
            updateUILog("发送APK文件")
            val md5 = MD5Util.getAssertFileMD5(this@HidPageActivity, "supercall.apk") ?: ""
            updateUILog("获取的MD5是$md5,length=${md5.toByteArray().size}")
            mHidMsgManager.sendFile("supercall.apk", md5)
        }

        /**
         * 更新安卓质检App
         */
        fun clickUpdateApK() {
            updateUILog("click->点击了更新安卓质检App")
            val md5 = MD5Util.getAssertFileMD5(this@HidPageActivity, "supercall.apk") ?: ""
            val updateApk = UpdateBean(
                "update",
                UpdateData(
                    "appA",
                    "supercall.apk",
                    "1.0.1",
                    md5,
                    "com.zhaoliangji.simplifyupdoorcheck"
                )
            )
            updateUILog("更新app发送数据：" + JsonUtils.toJson(updateApk))
            mHidMsgManager.sendDataMsg(JsonUtils.toJson(updateApk).toByteArray())
        }


        //发送APK
        fun clickSendIpa() {
            updateUILog("发送APK文件")
            val md5 = MD5Util.getAssertFileMD5(this@HidPageActivity, "supercall.ipa") ?: ""
            updateUILog("获取的MD5是$md5,length=${md5.toByteArray().size}")
            mHidMsgManager.sendFile("supercall.ipa", md5)
        }


        /**
         * 更新IOS质检App
         */
        fun clickUpdateIpa() {
            updateUILog("click->点击了更新IOS ipa包")
            val md5 = MD5Util.getAssertFileMD5(this@HidPageActivity, "supercall.ipa") ?: ""
            val updateApk = UpdateBean(
                "update",
                UpdateData(
                    "appI",
                    "supercall.ipa",
                    "1.0.1",
                    md5,
                    "com.zhaoliangji.simplifyOnsiteInspection"
                )
            )
            updateUILog("更新app发送数据：" + JsonUtils.toJson(updateApk))
            mHidMsgManager.sendDataMsg(JsonUtils.toJson(updateApk).toByteArray())
        }

        //安装应用授权
        fun clickInstallAuth() {
            updateUILog("click->安装应用(授权)")
            mHidMsgManager.sendCmdMsg("INSTALL 1")//后边带1为授权与安装同时,不带为仅安装
        }

        //安装应用
        fun clickInstall() {
            updateUILog("click->安装应用")
            mHidMsgManager.sendCmdMsg("INSTALL")
        }

        //指示灯1(亮灭)
        fun clickLight1() {
            updateUILog("click->指示灯1(亮灭)")
            mHidMsgManager.sendCmdMsg("LIGHT1 2")//预设0关1开2反向(开关状态互换),不带盒子会发送一个当前指示灯状态
        }

        //指示灯2(亮灭)
        fun clickLight2() {
            updateUILog("click->指示灯2(亮灭)")
            mHidMsgManager.sendCmdMsg("LIGHT2 2")//预设0关1开2反向(开关状态互换),不带盒子会发送一个当前指示灯状态
        }

        //获取获取Info
        fun clickGetInfo() {
            updateUILog("click->获取Info")
            if (mState.connectStatus.value == CmdLinkStatus.END_READ) {
                mHidMsgManager.sendCmdMsg("GETINFO")
            }
        }

        /**
         * 更新安卓质检App
         */
        fun clickSendFirmware() {
            updateUILog("准备发送固件包")
            val path = HidUtil.getFirmWarePath()
            val md5 = HidUtil.getSdCardFileMd5(path)
            updateUILog("固件包路径：$path")
            updateUILog("固件包MD5：$md5")
            if (md5.isNullOrEmpty()) {
                showShortToast("获取文件MD5失败")
                updateUILog("获取文件MD5失败")
                return
            }
            if (!mHidMsgManager.sendFileFromSdCard(HidContants.FIRM_WARE, path, md5)) {
                showShortToast("文件头发送失败")
            }
        }

        /**
         * 更新安卓质检App
         */
        fun clickUpdateFirmware() {
            updateUILog("click->点击了更新固件包")
            val path = HidUtil.getFirmWarePath()
            val md5 = HidUtil.getSdCardFileMd5(path)
            val md5config = HidUtil.getFirmwareMd5Config()
            if (md5.isNullOrEmpty()) {
                showShortToast("获取tar包文件MD5失败")
                updateUILog("获取tar包文件MD5失败")
                return
            }
            if (md5config.isNullOrEmpty()) {
                showShortToast("获取文件MD5config失败")
                updateUILog("获取文件MD5config失败")
                return
            }
            val updateApk = UpdateBean(
                "update",
                UpdateData("liangjitool", HidContants.FIRM_WARE, "1.1.0", md5, "", md5config)
            )
            updateUILog("更新固件包发送数据：" + JsonUtils.toJson(updateApk))
            mHidMsgManager.sendDataMsg(JsonUtils.toJson(updateApk).toByteArray())
        }


        //清空日志
        fun clickClear() {
            showShortToast("清空日志")
            mTvLog.text = ""
        }
    }
}